package com.wonderful.eyepetizer.view

import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.interaction.collectIsDraggedAsState
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Card
import androidx.compose.material.ContentAlpha
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.LocalContentAlpha
import androidx.compose.material.LocalContentColor
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.unit.dp
import coil.compose.rememberAsyncImagePainter
import com.wonderful.eyepetizer.app.ktx.visualTransition
import com.wonderful.eyepetizer.ui.theme.Black_12
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

/**
 * Desc: 轮播图
 * @Author: wonderful
 * @Time: 2024/1/24 12:19
 */

/**
 * @param data 数据源
 * @param onImgPath 图片 url
 * @param modifier Box 的 Modifier
 * @param ratio 图片宽高压缩比
 * @param contentScale 图片裁剪方式
 * @param isShowIndicator 是否显示指示器
 * @param indicatorModifier 指示器 row 的整个 Modifier
 * @param indicatorActiveColor 指示器选中颜色
 * @param indicatorNormalColor 指示器未选中颜色
 * @param isLoopBanner 是否自动轮播图
 * @param loopPeriod 轮播间隔时间（毫秒）
 * @param onDesc 文本内容
 * @param onBannerItemClick banner item 点击事件
 */
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class)
@Composable
fun <T> Banner(
    data: List<T>,
    onImgPath: (Int) -> String,
    modifier: Modifier = Modifier,
    ratio: Float = 7 / 3f,
    contentScale: ContentScale = ContentScale.Crop,
    isShowIndicator: Boolean = true,
    indicatorModifier: Modifier = Modifier,
    indicatorActiveColor: Color = Color.White,
    indicatorNormalColor: Color = Color(0xFF999999),
    isLoopBanner: Boolean = true,
    loopPeriod: Long = 5000,
    onDesc: @Composable ((Int) -> Unit)? = null,
    onBannerItemClick: ((Int) -> Unit)? = null
) {
    val pageCount = data.size
    val pagerState = rememberPagerState { pageCount }
    val isDragged by pagerState.interactionSource.collectIsDraggedAsState()
    var curPageKey by remember { mutableIntStateOf(0) }

    if (isLoopBanner && isDragged.not()) {
        with(pagerState) {
            if (pageCount > 0) {
                LaunchedEffect(key1 = curPageKey) {
                    launch {
                        delay(timeMillis = loopPeriod)
                        val nextPage = (currentPage + 1).mod(pageCount)
                        animateScrollToPage(page = nextPage, animationSpec = tween(500))
                        curPageKey = nextPage
                    }
                }
            }
        }
    }

    Box(modifier = modifier) {
        HorizontalPager(state = pagerState) { index ->
            Card(onClick = {
                onBannerItemClick?.invoke(index)
            }, modifier = Modifier.visualTransition(index, pagerState)) {
                Image(
                    painter = rememberAsyncImagePainter(model = onImgPath(index)),
                    contentDescription = null,
                    modifier = Modifier
                        .layoutId("image")
                        .fillMaxWidth()
                        .aspectRatio(ratio),
                    contentScale = contentScale
                )
            }
        }

        if (isShowIndicator) {
            Column(
                modifier = Modifier
                    .height(40.dp)
                    .fillMaxWidth()
                    .background(Black_12)
                    .padding(start = 5.dp, end = 5.dp)
                    .align(Alignment.BottomCenter),
            ) {
                onDesc?.invoke(curPageKey)
                DotIndicators(
                    pageCount = pageCount,
                    pagerState = pagerState,
                    modifier = indicatorModifier,
                    activeColor = indicatorActiveColor,
                    normalColor = indicatorNormalColor
                )
            }
        }
    }
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun DotIndicators(
    pageCount: Int,
    pagerState: PagerState,
    modifier: Modifier,
    activeColor: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current),
    normalColor: Color = activeColor.copy(ContentAlpha.disabled)
) {
    Row(modifier = modifier, horizontalArrangement = Arrangement.Center) {
        repeat(pageCount) {
            val color = if (pagerState.currentPage == it) activeColor else normalColor
            Box(
                modifier = Modifier
                    .padding(2.dp)
                    .clip(CircleShape)
                    .background(color)
                    .size(8.dp)
            )
        }
    }
}